
<template>
  <!-- append-to-body="true" 是为了不被前面对话框遮挡 by nbacheng -->
  <el-drawer
    :append-to-body="true"
    size="550px"
    class="drawer"
    v-model="visible"
    :show-close="false"
    style="text-align:left;"
    @close="cancel"
    v-if="properties"
  >
    <!-- 标题 -->
    <template #header="{ close, titleId, titleClass }" v-if="value && value.type=='start' && properties.title">
      <header class="header" style="height: 100%;"  >{{properties.title}}</header>
    </template>
    <template #header="{ close, titleId, titleClass }" v-else>
      <header class="header" style="height: 100%;" >
        <span @click="titleInputVisible = true" v-show="!titleInputVisible" style="cursor:pointer;">
          {{properties.title}}
          <el-icon class="el-icon-edit"><Edit /></el-icon>
        </span>
        <el-input
          size="small"
          v-model="properties.title"
          v-show="titleInputVisible"
          v-click-outside="()=> { titleInputVisible=false }"
          style="z-index:9;max-width: 200px;"
        />
        <el-select
          v-if="isConditionNode()"
          v-model="properties.priority"
          size="small"
          class="priority-select" >
          <el-option v-for="item in priorityLength" :key="item" :value="item-1" :label="'优先级'+item"></el-option>
        </el-select>
      </header>
    </template>

    <!-- 条件  -->
    <section class="condition-pane" v-if="value && isConditionNode()">
      <!-- 字符串条件 -->
      <el-input placeholder="请输入条件表达式" v-model="pconditions">
          <template slot="prepend">条件表达式:</template>
        </el-input>
    </section>

    <!-- 延时处理 -->
    <section  v-if="value && isDelayNode()" style="padding-left: 1rem;">
      <div>
        <div style="margin-bottom: 20px">
          <p class="item-desc">延时方式</p>
          <el-radio-group v-model="value.properties.type" size="small">
            <el-radio-button label="FIXED">固定时长</el-radio-button>
            <el-radio-button label="AUTO">自动计算</el-radio-button>
          </el-radio-group>
        </div>
        <div v-if="value.properties.type === 'FIXED'">
          <el-input style="width: 180px;" placeholder="时间单位" size="small" type="number" v-model="value.properties.time">
            <el-select style="width: 75px;" v-model="value.properties.unit" slot="append" placeholder="请选择">
              <el-option label="天" value="D"></el-option>
              <el-option label="小时" value="H"></el-option>
              <el-option label="分钟" value="M"></el-option>
            </el-select>
          </el-input>
          <span class="item-desc"> 后进入下一步</span>
        </div>
        <div class="item-desc" v-else>
          <el-time-picker value-format="HH:mm:ss" style="width: 150px;" size="small" v-model="value.properties.dateTime" placeholder="任意时间点"></el-time-picker>
          <span class="item-desc"> 后进入下一步</span>
        </div>
      </div>
    </section>

    <!-- 审批人 -->
    <section class="approver-pane" style="height:100%;" v-if="value && (isApproverNode() || isStartNode())">
      <el-tabs v-model="activeName"  class="pane-tab">
        <el-tab-pane :label="'设置' + (value.type === 'approver' ? '审批人' : '发起人')" name="config">
          <!-- 开始节点 -->
          <el-row style="padding: 10px;"  v-if="value.type === 'start'">
            <el-col :span="4" style="font-size: 12px;">发起人</el-col>
            <el-col :span="18" style="padding-left: 12px;">
              <!--<fc-org-select ref="start-org" :tabList="['dep&user']" v-model="initiator" /> -->
            </el-col>
          </el-row>

          <div v-else-if="value.type === 'approver'">
            <div style="padding: 12px;">
              <el-radio-group v-model="approverForm.assigneeType" style="line-height: 32px;" @change="resetOrgColl">
                <el-radio v-for="item in assigneeTypeOptions" :label="item.value" :key="item.value" class="radio-item">{{item.label}}</el-radio>
              </el-radio-group>
            </div>
            <div style="border-bottom: 1px solid #e5e5e5;padding-bottom: 1rem;">
              <div v-if="approverForm.assigneeType === 'myself'"  class="option-box" style="color: #a5a5a5;">发起人自己将作为审批人处理审批单</div>
              <div v-else-if="approverForm.assigneeType === 'optional'"  class="option-box">
                <p>可选多人</p>
                <el-switch v-model="approverForm.optionalMultiUser" active-color="#13ce66"> </el-switch>
                <p>选择范围</p>
                <el-select v-model="approverForm.optionalRange" size="small">
                  <el-option v-for="(item, index) in rangeOptions" :key="index" :label="item.label" :value="item.value"
                    :disabled="item.disabled"></el-option>
                </el-select>
              </div>
              <div v-else-if="approverForm.assigneeType === 'director'">
                <div style="font-size: 14px;padding-left: 1rem;">发起人的
                  <el-select v-model="directorLevel" size="small">
                    <el-option v-for="item in 5" :key="item" :label="item === 1 ? '直接主管': `第${item}级主管`" :value="item" />
                  </el-select>
                  <br>
                  <el-checkbox v-model="useDirectorProxy" style="margin-top: 1rem;">找不到主管时，由上级主管代审批</el-checkbox>
                </div>
              </div>
              <div v-else-if="approverForm.assigneeType === 'role'">
                <el-select v-model="roleIds" multiple size="small" placeholder="请选择 角色" @change="changeSelectRoles">
                  <el-option
                    v-for="item in roleOptions"
                    :key="item.roleId"
                    :label="item.roleName"
                    :value="`ROLE${item.roleId}`"
                    :disabled="item.status === 1">
                  </el-option>
                </el-select>
              </div>
              <div v-else class="option-box">
                <div class="element-drawer__button">
                  <el-button size="small" type="primary" icon="el-icon-plus" @click="onSelectUsers()">添加用户</el-button>
                </div>
                <el-tag v-for="userText in selectedUser.text" :key="userText" effect="plain">
                  {{userText}}
                </el-tag>
              </div>
            </div>
            <div class="option-box" style="border-bottom: 1px solid #e5e5e5;"
              v-if="orgCollection[approverForm.assigneeType]
              && orgCollection[approverForm.assigneeType].length > 1
              || ['optional'].includes(approverForm.assigneeType)
              || (['role'].includes(approverForm.assigneeType) && orgCollection[approverForm.assigneeType].length>=1)">
              <p>多人审批时采用的审批方式</p>
              <el-radio v-model="approverForm.counterSign" :label="true" class="radio-item">会签（须所有审批人同意）</el-radio>
              <br>
              <el-radio  v-model="approverForm.counterSign"  :label="false" class="radio-item">或签（一名审批人同意或拒绝即可）</el-radio>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="表单选择" name="formSelect">
           <el-form size="small" label-width="90px" @submit.native.prevent>
             <el-form-item label="表单" prop="formKey">
               <el-select v-model="approverForm.formKey" placeholder="请选择表单" @change="updateFormKey" clearable>
                 <el-option v-for="item in formOptions" :key="item.formId" :label="item.formName" :value="`key_${item.formId}`" />
               </el-select>
             </el-form-item>
             <el-form-item prop="localScope">
               <span slot="label">
                 <el-tooltip content="若为节点表单，则表单信息仅在此节点可用，默认为全局表单，表单信息在整个流程实例中可用" placement="top-start">
                   <i class="header-icon el-icon-info"></i>
                 </el-tooltip>
                 <span>节点表单</span>
               </span>
               <el-switch :disabled="value.type === 'start'" v-model="localScope" active-text="是" inactive-text="否" @change="updateFormScope()" />
             </el-form-item>
           </el-form>
        </el-tab-pane>
      </el-tabs>
    </section>

    <section  v-if="value && isCopyNode()" style="padding-left: 1rem;">
      <p>抄送人</p>
      <!--<fc-org-select ref="copy-org" v-model="properties.members" buttonType="button" title="抄送人" /> -->
      <br>
      <el-checkbox v-model="properties.userOptional">允许发起人自选抄送人</el-checkbox>
    </section>
    <div class="actions">
      <el-button size="small" @click="cancel">取消</el-button>
      <el-button size="small" type="primary" @click="confirm">确定</el-button>
    </div>
    <!-- 候选用户弹窗 -->
    <el-dialog title="候选用户" :visible.sync="userOpen" width="60%" append-to-body>
      <el-row type="flex" :gutter="20">
        <!--部门数据-->
        <el-col :span="7">
          <el-card shadow="never" style="height: 100%">
            <div slot="header">
              <span>部门列表</span>
            </div>
            <div class="head-container">
              <el-input
                v-model="deptName"
                placeholder="请输入部门名称"
                clearable
                size="small"
                prefix-icon="el-icon-search"
                style="margin-bottom: 20px"
              />
              <el-tree
                :data="deptOptions"
                :props="deptProps"
                :expand-on-click-node="false"
                :filter-node-method="filterNode"
                ref="tree"
                default-expand-all
                @node-click="handleNodeClick"
              />
            </div>
          </el-card>
        </el-col>
        <el-col :span="17">
          <el-table ref="multipleTable" height="600" :data="userTableList" border @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="50" align="center" />
            <el-table-column label="用户名" align="center" prop="nickName" />
            <el-table-column label="部门" align="center" prop="dept.deptName" />
          </el-table>
          <pagination
            :total="userTotal"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getUserList"
          />
        </el-col>
      </el-row>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleTaskUserComplete">确 定</el-button>
        <el-button @click="userOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, watch, onMounted } from 'vue';
import { listUser, deptTreeSelect } from "@/api/system/user";
import { listRole } from "@/api/system/role";
import { listForm } from "@/api/workflow/form";
import { NodeUtils } from "../FlowCard/util.js";
import RowWrapper from './RowWrapper';
import NumInput from "./NumInput";
import { ClickOutside as vClickOutside } from 'element-plus'

const rangeType = {
  'lt': '<',
  'lte': '≤',
  'gt': '>',
  'gte': '≥',
  'eq': '=',
};

const defaultApproverForm = {
  approvers: [], // 审批人集合
  assigneeType: "user", // 指定审批人
  formKey: "",  //挂载表单
  formOperates: [], // 表单操作权限集合
  counterSign: true, //是否为会签
  optionalMultiUser: false,
  optionalRange: 'ALL', // USER<最多十个> / ALL / ROLE
};

const props = defineProps(['value', 'processData']);
const emit = defineEmits(['confirm', 'cancel']);

const fcOrgTabList = ref(['dep', 'role', 'user', 'position']);
const visible = ref(false);
const globalFormOperate = ref(null);
const titleInputVisible = ref(false);
const activeName = ref("config");
const showingPCons = ref("{填写条件表达式}");
const pconditions = ref("{填写条件表达式}");
const dialogVisible = ref(false);
let properties = reactive({});
const initiator = reactive({ 'dep&user': [] });
const priorityLength = ref(0);
const orgCollection = reactive({ dep: [], role: [], user: [], position: [] });
const useDirectorProxy = ref(true);
const directorLevel = ref(1);
const startForm = reactive({ formOperates: [], formKey: "" });
const approverForm = reactive(JSON.parse(JSON.stringify(defaultApproverForm)));

const optionalOptions = ref([
  { label: '自选一个人', value: false },
  { label: '自选多个人', value: true },
]);

const rangeOptions = ref([
  { label: '全公司', value: 'ALL' },
  { label: '指定成员', value: 'USER' },
  { label: '角色', value: 'ROLE' },
]);

const assigneeTypeOptions = ref([
  { label: '指定成员', value: 'user' },
  { label: '主管', value: 'director' },
  { label: '角色', value: 'role' },
  { label: '发起人', value: 'myself' },
]);

const selectedUser = reactive({ ids: [], text: [] });
const userOpen = ref(false);
const deptName = ref(undefined);
const deptOptions = ref([]);
const deptProps = reactive({ children: "children", label: "label" });
const deptTempOptions = ref([]);
const userTableList = ref([]);
const userTotal = ref(0);
const selectedUserDate = ref([]);
const roleOptions = ref([]);
const roleIds = ref([]);
const deptTreeData = ref([]);
const deptIds = ref([]);
const queryParams = reactive({ deptId: undefined });
const formOptions = ref([]);
const formKey = ref("");
const localScope = ref(false);

watch(visible, (val) => {
  if (!val) {
    approverForm.value = JSON.parse(JSON.stringify(defaultApproverForm));
    return;
  }
  props.processData.properties.formOperates = initFormOperates(props.processData).map(t => ({ formId: t.formId, formOperate: t.formOperate }));
  isStartNode() && initStartNodeData();
  isApproverNode() && initApproverNodeData();
  isConditionNode() && initConditionNodeData();
});

watch(() => props.value, (newVal) => {
  if (newVal && newVal.properties) {
    visible.value = true;
    properties = JSON.parse(JSON.stringify(newVal.properties));
    if (properties) {
      NodeUtils.isConditionNode(newVal) && getPriorityLength();
    }
  }
}, { deep: true });

onMounted(() => {
  getFormList();
});

function onSelectUsers() {
  selectedUserDate.value = [];
  // 假设有一个方法来清除选择
  clearSelection();
  getDeptOptions();
  userOpen.value = true;
}

function clearOptionsData() {
  selectedUser.value.ids = [];
  selectedUser.value.text = [];
  roleIds.value = [];
  deptIds.value = [];
}

function getUserList() {
  listUser(queryParams.value).then(response => {
    userTableList.value = response.rows;
    userTotal.value = response.total;
  });
}

function getDeptOptions() {
  return new Promise((resolve, reject) => {
    if (!deptOptions.value.length) {
      deptTreeSelect().then(response => {
        deptTempOptions.value = response.data;
        deptOptions.value = response.data;
        resolve();
      });
    } else {
      reject();
    }
  });
}

function getDeptTreeData() {
  function refactorTree(data) {
    return data.map(node => {
      let treeData = { id: `DEPT${node.id}`, label: node.label, parentId: node.parentId, weight: node.weight };
      if (node.children && node.children.length > 0) {
        treeData.children = refactorTree(node.children);
      }
      return treeData;
    });
  }
  return new Promise((resolve, reject) => {
    if (!deptTreeData.value.length) {
      getDeptOptions().then(() => {
        deptTreeData.value = refactorTree(deptOptions.value);
        resolve();
      }).catch(() => {
        reject();
      });
    } else {
      resolve();
    }
  });
}

function getRoleOptions() {
  if (!roleOptions.value.length) {
    listRole().then(response => roleOptions.value = response.rows);
  }
}

function filterNode(value, data) {
  if (!value) return true;
  return data.label.indexOf(value) !== -1;
}

function handleNodeClick(data) {
  queryParams.value.deptId = data.id;
  getUserList();
}

function handleSelectionChange(selection) {
  selectedUserDate.value = selection;
}

function handleTaskUserComplete() {
  if (!selectedUserDate.value.length) {
    // 假设有一个方法来显示错误消息
    showError('请选择用户');
    return;
  }
  console.log("handleTaskUserComplete selectedUserDate", selectedUserDate.value);
  orgCollection.value.user = selectedUserDate.value;
  approverForm.text = selectedUserDate.value.map(k => k.nickName).join() || null;
  selectedUser.value.text = selectedUserDate.value.map(k => k.nickName) || [];
  userOpen.value = false;
}

function changeSelectRoles(val) {
  let groups = null;
  let text = null;
  let textArr = null;
  if (val && val.length > 0) {
    groups = val.join() || null;
    textArr = roleOptions.value.filter(k => val.indexOf(`ROLE${k.roleId}`) >= 0);
    text = textArr.map(k => k.roleName).join() || null;
  }
  approverForm.text = text;
  orgCollection.role = textArr;
}

function getFormList() {
  listForm().then(response => formOptions.value = response.rows);
}

function updateFormKey(formKey) {
  console.log("updateFormKey formKey", formKey);
  startForm.formKey = formKey;
}

function getFormOperates() {
  let res = [];
  if (isApproverNode()) res = approverForm.formOperates;
  if (isStartNode()) res = startForm.formOperates;
  return res;
}

function resetOrgColl() {
  for (let key in orgCollection) {
    orgCollection[key] = [];
  }
  getRoleOptions();
}

function timeTangeLabel(item) {
  const index = ['fc-time-duration', 'fc-date-duration'].findIndex(t => t === item.tag);
  if (index > -1) {
    return '时长' + ['(小时)', '(天)'][index];
  } else {
    return item.label;
  }
}

function getAssignTypeLabel() {
  const res = assigneeTypeOptions.value.find(t => t.value === approverForm.assigneeType);
  return res ? res.label : '';
}

function changeAllFormOperate(val) {
  const target = isStartNode() ? startForm : approverForm;
  target.formOperates.forEach(t => t.formOperate = val);
}

function couldShowIt(item, ...tag) {
  return tag.includes(item.tag);
}

function initFormOperates(target) {
  const formOperates = target.properties && target.properties.formOperates || [];
  const res = [];
  const defaultType = isApproverNode() ? 1 : 2;
  const getPermissionById = id => {
    const permission = formOperates.find(t => t.formId === id);
    return permission !== undefined ? permission.formOperate : defaultType;
  };
  const format = (list, parentName = '') => list.map(t => {
    const data = {
      formId: t.formId,
      required: t.required,
      label: parentName ? [parentName, t.label].join('.') : t.label,
      formOperate: getPermissionById(t.formId),
    };
    res.push(data);
    if (Array.isArray(t.children)) format(t.children, t.label);
  });
  return res;
}

function initCopyNode() {
  properties = value.properties;
}

function initStartNodeData() {
  initInitiator();
  startForm.formOperates = initFormOperates(props.value);
  startForm.formKey = props.value.properties.formKey;
  approverForm.formKey = props.value.properties.formKey;
}

function copyNodeConfirm() {
  visible.value = false;
}

function conditionNodeComfirm() {
  properties.conditions = pconditions.value;
  properties.initiator = initiator['dep&user'];
  emit('confirm', properties, pconditions.value || '请设置条件表达式');
  visible.value = false;
}

function getOrgSelectLabel(type) {
  return ref[type + '-org']['selectedLabels'];
}

function startNodeComfirm() {
  console.log("startNodeComfirm startForm", startForm);
  properties.initiator = initiator['dep&user'];
  properties.formKey = startForm.formKey;
  const formOperates = startForm.formOperates.map(t => ({ formId: t.formId, formOperate: t.formOperate }));
  Object.assign(properties, startForm, { formOperates });
  emit('confirm', properties, '所有人');
  console.log("startNodeComfirm properties", properties);
  visible.value = false;
}

function approverNodeComfirm() {
  console.log("approverNodeComfirm approverForm", approverForm);
  const assigneeType = approverForm.assigneeType;
  let content = '';
  if (['optional', 'myself'].includes(assigneeType)) {
    content = assigneeTypeOptions.value.find(t => t.value === assigneeType).label;
  } else if ('director' === assigneeType) {
    content = directorLevel.value === 1 ? '直接主管' : `第${directorLevel.value}级主管`;
  } else {
    content = approverForm.text;
  }
  const formOperates = approverForm.formOperates.map(t => ({ formId: t.formId, formOperate: t.formOperate }));
  approverForm.approvers = orgCollection[assigneeType];
  Object.assign(properties, approverForm, { formOperates });
  emit('confirm', properties, content || '请设置审批人');
  visible.value = false;
}

function delayNodeComfirm() {
  console.log("delayNodeComfirm value", props.value);
  let content = '';
  if (props.value.properties.type === "FIXED") {
    content = "等待" + props.value.properties.time + "分钟";
  } else if (props.value.properties.type === "AUTO") {
    content = "到当天" + props.value.properties.dateTime;
  }
  const formOperates = startForm.formOperates.map(t => ({ formId: t.formId, formOperate: t.formOperate }));
  Object.assign(properties, props.value.properties, { formOperates });
  emit('confirm', properties, content || '请设置延时时间');
  visible.value = false;
}

function confirm() {
  if (isCopyNode()) {
    copyNodeConfirm();
  } else if (isStartNode()) {
    startNodeComfirm();
  } else if (isApproverNode()) {
    approverNodeComfirm();
  } else if (isConditionNode()) {
    conditionNodeComfirm();
  } else if (isDelayNode()) {
    delayNodeComfirm();
  }
}

function cancel() {
  setTimeout(() => {
    emit('cancel');
    visible.value = false;
  }, 0);
}

function getPrevData() {
  return NodeUtils.getPreviousNode(value.prevId, props.processData);
}

function getPriorityLength() {
  priorityLength.value = getPrevData().conditionNodes.length;
}

function isConditionNode() {
  return props.value ? NodeUtils.isConditionNode(props.value) : false;
}

function isDelayNode() {
  return props.value ? NodeUtils.isDelayNode(props.value) : false;
}

function isApproverNode() {
  return props.value ? NodeUtils.isApproverNode(props.value) : false;
}

function isStartNode() {
  return props.value ? NodeUtils.isStartNode(props.value) : false;
}

function isCopyNode() {
  return props.value ? NodeUtils.isCopyNode(props.value) : false;
}

function initInitiator() {
  const initiator = value.properties && value.properties.initiator;
  initiator['dep&user'] = Array.isArray(initiator) ? initiator : [];
}

function initApproverNodeData() {
  for (const key in approverForm) {
    if (props.value.properties.hasOwnProperty(key)) {
      approverForm[key] = props.value.properties[key];
    }
  }
  const approvers = approverForm.approvers;
  resetOrgColl();
  if (approverForm.assigneeType === 'user') {
    orgCollection[approverForm.assigneeType] = approvers;
    selectedUser.text = approvers.map(k => k.nickName) || [];
    approverForm.text = approvers.map(k => k.nickName).join() || null;
  } else if (approverForm.assigneeType === 'role') {
    orgCollection[approverForm.assigneeType] = approvers;
    approverForm.text = approvers.map(k => k.roleName).join() || null;
  }
  approverForm.formOperates = initFormOperates(props.value);
}

function initConditionNodeData() {
  pconditions.value = props.value.content;
}
</script>

<style lang="scss">
.condition-dialog {
  .el-dialog__header{
    border-bottom : 1px solid #eee;
  }
}

</style>
<style lang="scss" scoped>
.drawer {
  >>> .el-drawer__header {
    margin-bottom: 0;
    border-bottom: 1px solid #c5c5c5;
    padding-bottom: 8px;
  }

  >>> .el-drawer__body {
    padding-bottom: 44px;
    overflow: hidden;
  }

  .pane-tab{
    height: 100%;
  }

  .pane-tab >>>  .el-tabs__item.is-top:nth-child(2) {
    padding-left: 20px;
  }

  >>> .el-tabs__item:focus{
    box-shadow: none !important;
  }

  >>> .el-tabs__header {
    margin-bottom: 0;
  }
}

.header {
  line-height: 28px;
}

.actions {
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 6px 12px;
  width: 100%;
  box-sizing: border-box;
  text-align: right;
}

.radio-item {
  width: 110px;
  padding: 6px;
}

.priority-select {
  width: 118px;
  position: absolute;
  right: 26px;
}

.form-auth-table{
  font-size: 14px;
  .auth-table-header{
    background: #fafafa;
    line-height: 40px;
  }
  .row{
    display: flex;
    align-items: center;
    line-height: 32px;
    padding: 8px 12px;
    border-bottom: 1px solid #efefef;
    &:hover{
      background: #f5f7fa;
    }
    .label{
      flex:1;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;

      .required{
        color: #f2725e;
      }
    }
    .radio-group{
      flex: 2;
      display: flex;
      justify-content: space-between;
    }
  }
}

.approver-pane{
  overflow-y: scroll;
  overflow-x: hidden;
  .option-box {
    font-size: 14px;
    padding-left: 1rem;
  }
}

.condition-pane{
  height: 100%;
  overflow: scroll;
}
</style>
